package com.example.admin.brainwave.ui.activity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.admin.brainwave.BluetoothServers;
import com.example.admin.brainwave.R;
import com.example.admin.brainwave.base.BaseActivity;
import com.example.admin.brainwave.bean.BeaconDevice;
import com.example.admin.brainwave.ui.adapter.MyBluetoothAdapter;
import com.example.admin.brainwave.ui.adapter.PairAdapter;
import com.example.admin.brainwave.utils.ClsUtils;
import com.example.admin.brainwave.utils.Const;
import com.suke.widget.SwitchButton;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;

public class BluetoothActivity extends BaseActivity {


    @BindView(R.id.iv_top_back)
    ImageView ivTopBack;
    @BindView(R.id.tv_top_title)
    TextView tvTopTitle;
    @BindView(R.id.iv_top_login_out)
    ImageView ivTopLoginOut;
    @BindView(R.id.tv_top_right)
    TextView tvTopRight;
    @BindView(R.id.iv_top_connect)
    ImageView ivTopConnect;
    @BindView(R.id.sb_bluetooth_bt)
    SwitchButton sbBluetoothBt;
    @BindView(R.id.sb_bluetooth_kf)
    SwitchButton sbBluetoothKf;
    @BindView(R.id.rv_bluetooth_pair_list)
    RecyclerView rvBluetoothPairList;
    @BindView(R.id.rv_bluetooth_usable_list)
    RecyclerView rvBluetoothUsableList;
    @BindView(R.id.btn_bluetooth_completion)
    Button btnBluetoothCompletion;

    private Timer mTimer;
    private PairAdapter pairAdapter;
    private MyBluetoothAdapter mbluetoothAdapter;
    private List<BeaconDevice> data = new ArrayList<>();
    private long minPeriod = 2000;


    private BluetoothAdapter bluetoothAdapter;
    private static final int MIN_DELAY = 600;
    private static final int MIN_PERIOD = 2000;
    private ArrayList<BeaconDevice> mDeviceList = new ArrayList<>();

    private static final int REQUEST_CODE_BLUETOOTH_ON = 1313;
    private static final int BLUETOOTH_DISCOVERABLE_DURATION = 250;
    private Handler mHandlerTimer;


    @Override
    protected int attachLayoutRes() {
        return R.layout.activity_bluetooth;
    }

    @Override
    protected void initView() {
        tvTopTitle.setText(getResources().getString(R.string.bluetooth));
        mHandlerTimer = new Handler();
        mTimer = new Timer();
        rvBluetoothUsableList.setLayoutManager(new LinearLayoutManager(this));
        rvBluetoothPairList.setLayoutManager(new LinearLayoutManager(this));
        pairAdapter = new PairAdapter(R.layout.item_bluetooth_pair, new ArrayList<>());
        rvBluetoothPairList.setAdapter(pairAdapter);
        mbluetoothAdapter = new MyBluetoothAdapter(R.layout.item_bluetooth_pair, new ArrayList<>());
        rvBluetoothUsableList.setAdapter(mbluetoothAdapter);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        setBluetoothState();
    }


    private void setBluetoothState() {
        if (bluetoothAdapter.isEnabled()) {
            sbBluetoothBt.setChecked(true);
            start(minPeriod);
            setPair();
        }
        regeditReceiver();
    }


    private void setPair() {
        data.clear();
        Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
        if (devices.size() > 0) {
            for (BluetoothDevice bluetoothDevice : devices) {
                data.add(new BeaconDevice(bluetoothDevice.getName(), bluetoothDevice.getAddress(), bluetoothDevice));
            }
            pairAdapter.setNewData(data);
        }
    }


    private void regeditReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(mBluetoothReceiver, filter);
    }


    @Override
    protected void addListener() {
        ivTopBack.setOnClickListener(view -> finish());
        btnBluetoothCompletion.setOnClickListener(view -> finish());
        sbBluetoothBt.setOnCheckedChangeListener((view, isChecked) -> {
            if (isChecked) {
                turnOnBluetooth();
                start(minPeriod);
                setPair();
            } else {
                sbBluetoothKf.setChecked(false);
                turnOffBluetooth();
                mbluetoothAdapter.getData().clear();
                mbluetoothAdapter.notifyDataSetChanged();
                pairAdapter.getData().clear();
                pairAdapter.notifyDataSetChanged();
            }
        });

        sbBluetoothKf.setOnCheckedChangeListener((view, isChecked) -> {
            if (isChecked) {
                openTestin();
            } else {
                closeTestin();
            }
        });

        pairAdapter.setOnItemClickListener((adapter, view, position) -> {
            try {
                ClsUtils.removeBond(mbluetoothAdapter.getData().get(position).getDevice().getClass(), mbluetoothAdapter.getData().get(position).getDevice());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        mbluetoothAdapter.setOnItemClickListener((adapter, view, position) -> {
            try {
                ClsUtils.createBond(mbluetoothAdapter.getData().get(position).getDevice().getClass(), mbluetoothAdapter.getData().get(position).getDevice());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }


    private void openTestin() {
        if (bluetoothAdapter.isEnabled()) {
            Intent requestBluetoothOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            requestBluetoothOn.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, BLUETOOTH_DISCOVERABLE_DURATION);
            startActivityForResult(requestBluetoothOn, REQUEST_CODE_BLUETOOTH_ON);
        }
    }

    private void closeTestin() {
        //尝试关闭蓝牙可见性
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);
            setDiscoverableTimeout.invoke(bluetoothAdapter, 1);
            setScanMode.invoke(bluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_BLUETOOTH_ON) {
            switch (resultCode) {
                case RESULT_CANCELED:
                    sbBluetoothKf.setChecked(false);
                    break;
            }
        }
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ArrayList<BeaconDevice> devices = (ArrayList<BeaconDevice>) msg.obj;
            if (devices != null && devices.size() > 0) {
                mbluetoothAdapter.getData().clear();
                mbluetoothAdapter.getData().addAll(devices);
                mbluetoothAdapter.notifyDataSetChanged();
            }
        }
    };


    private BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                addDevice(device);
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
                sendDevices();
            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
                    Toast.makeText(BluetoothActivity.this, "正在配对" + device.getName() + "请稍后", Toast.LENGTH_SHORT).show();
                } else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    if (pairAdapter.getData().size() > 0) {
                        for (int i = 0; i < pairAdapter.getData().size(); i++) {
                            if (device.getName().equals(pairAdapter.getData().get(i).getName())) {
                                pairAdapter.getData().remove(i);
                            }
                        }
                        pairAdapter.addData(new BeaconDevice(device.getName(), device.getAddress(), device));
                    } else {
                        pairAdapter.addData(new BeaconDevice(device.getName(), device.getAddress(), device));
                    }
                } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
                    Toast.makeText(BluetoothActivity.this, "取消配对" + device.getName() + "请稍后", Toast.LENGTH_SHORT).show();
                    for (int i = 0; i < pairAdapter.getData().size(); i++) {
                        if (device.getName().equals(pairAdapter.getData().get(i).getName())) {
                            pairAdapter.getData().remove(i);
                        }
                    }
                    pairAdapter.notifyDataSetChanged();

                }
            }
        }
    };


    public void addDevice(BluetoothDevice device) {
        BeaconDevice beaconDevice = new BeaconDevice(device.getName(), device.getAddress(), device);
        Iterator<BeaconDevice> iterator = mDeviceList.iterator();
        while (iterator.hasNext()) {
            if (device.getAddress().equals(iterator.next().getAddress()))
                iterator.remove();  //如果多次扫描到同一台设备，则移除之前的设备
        }
        mDeviceList.add(beaconDevice);
    }

    public void sendDevices() {
        Message msg = new Message();
        msg.obj = mDeviceList;
        mHandler.sendMessage(msg);
    }


    private void startDiscovery() {
        mDeviceList.clear(); // 每一次扫描之前要清除上一次扫描的设备
        if (bluetoothAdapter != null) {
            bluetoothAdapter.startDiscovery();
        }
        mHandlerTimer.postDelayed(() -> cancelDiscovery(), MIN_DELAY);
    }

    private void cancelDiscovery() {
        if (bluetoothAdapter != null) {
            bluetoothAdapter.cancelDiscovery();
        }
    }


    public boolean turnOnBluetooth() {
        if (bluetoothAdapter != null) {
            return bluetoothAdapter.enable();
        }
        return false;
    }

    public boolean turnOffBluetooth() {
        if (bluetoothAdapter != null) {
            return bluetoothAdapter.disable();
        }
        return false;
    }

    public void start(long period) {
        if (period <= 0) {
            period = MIN_PERIOD;
        }
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                startDiscovery();
            }
        }, 0, period);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mBluetoothReceiver);
        if (mTimer != null) {
            mTimer.cancel();
        }
    }
}
